#include "QPlot.h"
#include <cmath>

QPlot::QPlot(QWidget * /*parent*/): yMin(0), yMax(0), xSpace(30), ySpace(20)
{
    this->setMinimumSize(542, 41);
}

void QPlot::addPoint(QPointF point, int curveCount)
{
    if (curveCount<curveList.size()) curveList[curveCount].addPoint(point);
}

void QPlot::setPen(QPen pen, int curveCount)
{
    if (curveCount<curveList.size()) curveList[curveCount].setPen(pen);
}

void QPlot::calcMinMax(void)
{
    if (curveList.size())
    {
        yMin = curveList[0].getYMin();
        yMax = curveList[0].getYMax();
    }
    else
    {
        yMin = yMax = 0;
    }
    for (int i=0; i<curveList.size(); ++i)
    {
        if (curveList[i].getYMin() < yMin) yMin = curveList[i].getYMin();
        if (curveList[i].getYMax() > yMax) yMax = curveList[i].getYMax();
    }
}

QPointF QPlot::calcZeroPoint(void)
{
    double yZero = ySpace;
    if ((yMin*yMax <  0)||(yMin >= 0)) yZero += yMax;

    return QPointF(xSpace, yZero);
}
QPointF QPlot::calcRectPoint(void)
{
    double xRect = 0;
    double yRect = 0;

    if (curveList.size())
    {
        xRect += curveList[0].getLimit();
    }
    else
    {
        xRect += 541;
    }

    if (yMin*yMax < 0) yRect =  yMax - yMin;
    else if (yMin >= 0) yRect =  yMax;
    else if (yMax <  0) yRect = -yMin;

    QSize minimumSize(xRect+2*xSpace+1, yRect+2*ySpace+1);

    if (this->minimumSize() != minimumSize)
    {
        this->setMinimumSize(minimumSize);
    }

    return QPointF(xRect+2*xSpace, yRect+2*ySpace);
}

void QPlot::addCurve(void)
{
    QCurve curve;
    switch (curveList.length()%10)
    {
    case 0:
        curve.setPen(QPen(QColor(Qt::black)));
        break;
    case 1:
        curve.setPen(QPen(QColor(Qt::red)));
        break;
    case 2:
        curve.setPen(QPen(QColor(255,102,0)));
        break;
    case 3:
        curve.setPen(QPen(QColor(Qt::darkGreen)));
        break;
    case 4:
        curve.setPen(QPen(QColor(Qt::blue)));
        break;
    case 5:
        curve.setPen(QPen(QColor(Qt::darkCyan)));
        break;
    case 6:
        curve.setPen(QPen(QColor(Qt::darkBlue)));
        break;
    case 7:
        curve.setPen(QPen(QColor(Qt::darkMagenta)));
        break;
    case 8:
        curve.setPen(QPen(QColor(Qt::darkRed)));
        break;
    case 9:
        curve.setPen(QPen(QColor(Qt::darkGray)));
        break;
    }
    curveList << curve;
}

void QPlot::removeCurve(void)
{
    curveList.removeLast();
}

int QPlot::getCurveNum(void)
{
    return curveList.size();
}

void QPlot::paintEvent(QPaintEvent * /*event*/)
{
    this->calcMinMax();

    QPointF zeroPoint = this->calcZeroPoint();
    QPointF rectPoint = this->calcRectPoint();

    QPainter painter(this);

    painter.setBrush(QColor(250,250,250));
    painter.setPen(Qt::darkGray);
    painter.drawRect(0,0,rectPoint.x(),rectPoint.y());
    painter.drawLine(0,zeroPoint.y(),rectPoint.x(),zeroPoint.y());
    painter.drawLine(zeroPoint.x(),0,zeroPoint.x(),rectPoint.y());

    this->drawGrid(painter);

    painter.setRenderHint(QPainter::Antialiasing,true);
    for (int i=0; i<curveList.size(); ++i)
    {
        curveList[i].formatPoints(zeroPoint);
        painter.setPen(curveList[i].getPen());
        painter.drawPolyline(curveList[i].getPointsFormatted());
    }
}

void QPlot::drawGrid(QPainter &painter)
{
    QPointF zeroPoint = this->calcZeroPoint();
    QPointF rectPoint = this->calcRectPoint();

    QFont font;
    font.setPointSize(7);
    painter.setFont(font);

    this->resize(rectPoint.x()+1,rectPoint.y()+1);

    int xStep = 50;
    for (int i=1; i<12; ++i)
    {
        painter.drawLine(zeroPoint.x()+i*xStep,zeroPoint.y()-5,zeroPoint.x()+i*xStep,zeroPoint.y()+5);
        painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap));
        painter.drawLine(zeroPoint.x()+i*xStep, ySpace, zeroPoint.x()+i*xStep, rectPoint.y()-ySpace);
        painter.setPen(QPen(Qt::black));
        painter.drawText(zeroPoint.x()+(i-0.4)*xStep,zeroPoint.y() + 7,xStep,10,Qt::AlignCenter,QString().setNum(int(i*xStep)));
    }

    int yStep = 20;
    for (int i=1; i<12; ++i)
    {
        if (zeroPoint.y()+i*yStep <= (rectPoint.y()-ySpace)+11)
        {
            painter.drawLine(zeroPoint.x()-5, zeroPoint.y()+i*yStep, zeroPoint.x()+5, zeroPoint.y()+i*yStep);
            painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap));
            painter.drawLine(zeroPoint.x()+5, zeroPoint.y()+i*yStep, rectPoint.x()-5, zeroPoint.y()+i*yStep);
            painter.setPen(QPen(Qt::black));
            painter.drawText(zeroPoint.x()-xSpace,zeroPoint.y()+i*yStep - 5,xSpace,10,Qt::AlignCenter, QString().setNum(int(-i*yStep)));
        }
        if (zeroPoint.y()-i*yStep >= ySpace-11)
        {
            painter.drawLine(zeroPoint.x()-5, zeroPoint.y()-i*yStep, zeroPoint.x()+5, zeroPoint.y()-i*yStep);
            painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap));
            painter.drawLine(zeroPoint.x()+5, zeroPoint.y()-i*yStep, rectPoint.x()-5, zeroPoint.y()-i*yStep);
            painter.setPen(QPen(Qt::black));
            painter.drawText(zeroPoint.x()-xSpace, zeroPoint.y()-i*yStep - 5,xSpace,10,Qt::AlignCenter, QString().setNum(int(i*yStep)));
        }
    }
}
